package com.it.travel01.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.travel01.dao.UserDao;
import com.it.travel01.pojo.User;
import com.it.travel01.service.MessageService;
import com.it.travel01.service.UserService;
import com.it.travel01.utils.Md5Util;
import com.it.travel01.utils.UuidUtil;
import com.it.travel01.vo.ResultInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.mail.MessagingException;
import javax.servlet.http.HttpSession;

@Service("userService")
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)//适用于查询场景
public class UserServiceImpl extends ServiceImpl<UserDao,User> implements UserService {

    @Autowired
    private MessageService messageService;

    @Value("${constant.userkey}")
    private String userkey;

    /**
     * 注册
     * @param user
     * @param check
     * @param check_coder
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,readOnly = false)//适用于增删改场景
    public ResultInfo register(User user, String check, String check_coder) {
//        后台核心逻辑如下：
//        1.校验前端发送的验证码与后台session下的验证码是否一致；
        if (!check_coder.equalsIgnoreCase(check)) {
//        1.1 不一致，则返回(验证码错误)信息；
            return new ResultInfo(false,"验证码校验错误");
        }
//        1.2 一致，则进行下一步的操作；
//        2.判断用户信息是否合法
//                主要判断用户名或者密码是否为空
        if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPassword())) {
//        2.1 用户名或者密码为空，则返回(注册信息错误)错误信息
            return new ResultInfo(false,"用户名或密码错误");
        }
//        2.2 用户信息合法，则进行下一步操作；
//        3.检验当前用户名是否已被注册
//        User u = userDao.queryByName(user.getUsername());
        LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery(User.class);
        lambdaQueryWrapper.eq(User::getUsername, user.getUsername());
        User u = this.getOne(lambdaQueryWrapper);
        if (u != null) {
//        3.1 如果已注册，则返回(用户已经注册)错误信息
            return new ResultInfo(false,"用户已被注册");
        }
//        3.2 如果用户未注册，则进行下一步操作；
//        4.数据库插入用户信息
        user.setStatus("N");
        user.setPassword(Md5Util.encodeByMd5(user.getPassword()));
        String uuid = UuidUtil.getUuid();
        user.setCode(uuid);
//        Integer count=userDao.addUser(user);
        boolean iscount = this.save(user);
        if (!iscount) {
//        4.1 插入不成功，则返回(注册失败)错误信息
            return new ResultInfo(false,"添加用户失败");
        }
//        4.2 插入成成功，则进行下一步操作；
//        5.为当前注册用户发送激活邮件；
        String activatemsg = "<a href='http://localhost:80/user/activate?code=" + uuid + "'>点击激活</a>";
//        MailUtil.sendMail(user.getEmail(),activatemsg);
        String subject = "激活账号";
        try {
            messageService.sendMessage(user.getEmail(),subject,activatemsg);
        } catch (MessagingException e) {
            e.printStackTrace();
            throw new RuntimeException("邮件发送失败");
        }
//        6.用户添加功能与邮箱的发送功能保证事务一致；
//        6.1.方法之上添加事务支持
        return new ResultInfo(true,null,null);
    }


    /**
     * 激活修改状态码
     * @param code
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,readOnly = false)
    public Boolean activateUser(String code) {
/*//        1.后台获取激活码数据库，调用服务层校验；
        if (code ==null) {
//        1.1 激活码如果为空，则抛出业务异常；
            throw new RuntimeException("激活码为空");
        }*/
//        1.2 不为空则调用dao执行更新用户状态操作；
//        2.服务层调用dao层根据激活码更新用户信息
//        Integer count=userDao.updateCodeStatus(code);
        LambdaUpdateWrapper<User> updateWrapper = Wrappers.lambdaUpdate(User.class);
        updateWrapper.eq(User::getCode, code)
                .set(User::getStatus, "Y");
        boolean count = this.update(updateWrapper);
        if (!count) {
//        2.2 更新不成功,返回false
            return false;
        }

        return true;
    }

    /**
     * 账户登录
     * @param user
     * @param check
     * @param check_coder
     * @return
     */
    @Override
    public ResultInfo loginUser(User user, String check, String check_coder) {
        //判断验证码是否正确
        if (!check_coder.equalsIgnoreCase(check)) {
            //false
            return new ResultInfo(false,"验证码校验失败");
        }
        //判断用户和密码是否为空
        if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPassword())) {
            //只要有一个就false
            return new ResultInfo(false,"用户或密码错误");
        }
//        User u=userDao.queryByNameAndPwd(user.getUsername(),Md5Util.encodeByMd5(user.getPassword()));
        String s = Md5Util.encodeByMd5(user.getPassword());
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class);
        queryWrapper.eq(User::getUsername, user.getUsername())
                .eq(User::getPassword,s);
//        User u = this.getOne(queryWrapper);
        User u = baseMapper.selectOne(queryWrapper);
        if (u == null) {
            return new ResultInfo(false,"用户名不存在或密码错误");
        }

        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        ServletRequestAttributes attributes=(ServletRequestAttributes)requestAttributes;
        HttpSession session = attributes.getRequest().getSession();
        session.setAttribute(userkey,u);

        return new ResultInfo(true,null,null);
    }

    /**
     * 登录表头数据回显用户名
     * @return
     */
    @Override
    public ResultInfo getData() {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        ServletRequestAttributes attributes=(ServletRequestAttributes)requestAttributes;
        HttpSession session = attributes.getRequest().getSession();
        User user = (User) session.getAttribute(userkey);
        if (user == null) {
            return new ResultInfo(false,"用户未登录");
        }
        user.setPassword(null);
        user.setEmail(null);
        user.setCode(null);
        user.setStatus(null);
        return new ResultInfo(true,user,null);
    }


    /**
     * 登出
     * @return
     */
    @Override
    public Boolean loginOut() {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        ServletRequestAttributes attributes=(ServletRequestAttributes)requestAttributes;
        HttpSession session = attributes.getRequest().getSession();
        session.removeAttribute(userkey);
        return true;
    }


}
